using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace HindernisGame
{

    public class Hindernisse
    {
        private Game1 game;
        private Matrix[] worldMatrix;
        private Matrix viewMatrix;
        private SpriteBatch spriteBatch;
        private Random rnd = new Random();
        private float zPos, speedZ = 0.2f;
        private static int abstand = 25;
        private Model[] hindernisse;
        private int zCounter; // posi des letzten objekts
        private int intervall = 10;
        private int score = 0;
        private static float speedEnhancer = 0.1f / 750.0f;

        public Hindernisse(Game1 game)
        {
            this.game = game;
            hindernisse = new Model[11];
            worldMatrix = new Matrix[11];
        }

        public void Initialize()
        {
            for (int i = 0; i < 11; i++)
            {
                worldMatrix[i] = createRandomWorldMatrix(-i * abstand - abstand, i+9); //stellen 0-99
            }
        }

        private Matrix createRandomWorldMatrix(int zPos, int stelle)
        {
            int[] rand = new int[100];
            rand[0] = 4;
            for(int i = 1; i<100; i++) {
                int newR = rnd.Next(1, 5);
                if (rand[i - 1] == newR)
                    rand[i] = rnd.Next(1, 5);
                else rand[i] = newR;
            }
            zCounter -= intervall;
            switch (rand[stelle])
            {
                case (1): //links
                    return Matrix.CreateScale(0.5f) * Matrix.CreateTranslation(-2, 0, zPos) * Matrix.CreateScale(1, 2, 1);
                case (2): // mitte
                    return Matrix.CreateScale(0.5f) * Matrix.CreateTranslation(0, 0, zPos) * Matrix.CreateScale(1, 2, 1);
                case (3): // rechts
                    return Matrix.CreateScale(0.5f) * Matrix.CreateTranslation(2, 0, zPos) * Matrix.CreateScale(1, 2, 1);
                case (4): // unten(springen)
                    return Matrix.CreateScale(0.5f) * Matrix.CreateTranslation(0, -1, zPos) * Matrix.CreateScale(5, 1, 1);
            }
            return Matrix.CreateScale(0.5f);

        }

        public void LoadContent()
        {
            for (int i = 0; i < 11; i++)
            {
                hindernisse[i] = game.Content.Load<Model>("cube");
            }
            spriteBatch = new SpriteBatch(game.GraphicsDevice);
        }

        public void Update(GameTime gameTime)
        {
            if (zPos < worldMatrix[0].Translation.Z) //alle Abstand (25) z-schritte neues hindernis
            {
                for (int i = 0; i < 10; i++)
                {
                    worldMatrix[i] = worldMatrix[i + 1];
                }
                worldMatrix[10] = createRandomWorldMatrix((int)worldMatrix[10].Translation.Z - abstand, 55);

            }
            viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 2.0f, 5.0f + zPos), new Vector3(0.0f, 0.0f, zPos - 10.0f), Vector3.Up);

            zPos -= speedZ;
            speedZ += speedEnhancer;
            score = (int)zPos * -50;
        }

        public float getSpeedFactor()
        {
            return speedZ / 0.2f;
        }

        public int getScore()
        {
            return score;
        }

        public Matrix getMatrix0()
        {
            return worldMatrix[0];
        }

        public void Draw(GameTime gameTime)
        {  
            spriteBatch.Begin();            
            spriteBatch.Draw(game.background, new Rectangle(0, 0, game.GraphicsDevice.Viewport.Width, game.GraphicsDevice.Viewport.Height), Color.White);
            spriteBatch.DrawString(game.font, score.ToString() + " Punkte", new Vector2(10, 10), Color.WhiteSmoke);
            spriteBatch.End();

            for (int i = 10; i >= 0; i--)
            {
                DrawMethod(hindernisse[i], worldMatrix[i], viewMatrix);
            }
        }
        
        private void DrawMethod(Model model, Matrix wMatrix, Matrix viewMatrix)
        {
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = wMatrix;
                    effect.View = viewMatrix;
                    effect.Projection = game.projectionMatrix;
                    effect.EnableDefaultLighting();
                    effect.AmbientLightColor = Color.Black.ToVector3();
                }
                mesh.Draw();
            }
        }
    }
}